#include <iostream>
#include <string>
#include <thread>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/time.h>
#include <sys/stat.h>
//#include <sys/mman.h>
#include <sys/types.h>

#include "json_bean.h"
#include "easywsclient.hpp"

#ifdef _WIN32
#pragma comment( lib, "ws2_32" )
#include <WinSock2.h>
#endif

using easywsclient::WebSocket;
static WebSocket::pointer g_wsClient = nullptr;

void pfnOnHandleWSMessage(const std::string& message) {
    //printf(">>> receive message: %s.\r\n", message.c_str());
    //g_wsClient->close();
    //if (message == "world") { g_wsClient->close(); }
    return;
}

// 读出文件
void readFile(const std::string &strFilePath, std::string &strContent)
{
    std::ifstream fin(strFilePath);
    if (!(fin.is_open()))
    {
        printf("open file (%s) failed.\r\n", strFilePath.data());
        return;
    }
#if 0
    // 该方法效率一般，慎用
    std::istreambuf_iterator<char> iterBeg(fin), iterEnd;
    strContent = std::string(iterBeg, iterEnd);
#else
    // 该方法效率较一般读取方法快20倍
    std::vector<char> buffer;
    buffer.clear();
    buffer.resize(fin.seekg(0, std::ios::end).tellg());
    fin.seekg(0, std::ios::beg).read(&buffer[0], static_cast<std::streamsize>(buffer.size()));
    strContent = std::string(buffer.data(), buffer.size());
#endif
    fin.close();

    return;
}

int main(int argc, char **argv) {
    // 测试时的cmd和value通过输入参数实现，内生安全使能信息通过配置读取实现
    if (4 > argc) {
        printf("input agrv is error, must >= 4.\r\n");
        return 0;
    }

#ifdef _WIN32
    int rc;
    WSADATA wsaData;

    rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rc) {
        printf("WSAStartup Failed.\n");
        return 1;
    }
#endif

    std::string strWSAddr = "ws://" + std::string(argv[1]) + ":58080/test/v1/vehicle_control";
    int iCmdCode = atoi(argv[2]);
    int iValue = atoi(argv[3]);
#if 0
    // 读取内生安全使能信息的配置
    bool bEnableEndogenous = true;
    std::string strContent = "";
    readFile("/root/release/images/.ad_notify.config", strContent);
    if (std::string::npos != strContent.find("dhr=1")) {
        bEnableEndogenous = true;
    } else {
        bEnableEndogenous = false;
    }

    printf("read config file content: %s, endogenous status: %d.\r\n", strContent.data(), bEnableEndogenous);
#endif
    // 发送ws消息
    g_wsClient = WebSocket::from_url(strWSAddr);
    if (g_wsClient && (g_wsClient->getReadyState() == WebSocket::OPEN)) {
        JsonBean objBeanReq;
        //objBeanReq.add("endogenous", bEnableEndogenous);
        objBeanReq.add("cmdCode", iCmdCode);
        objBeanReq.add("value", iValue);

        std::string strData = objBeanReq.unformattedData();
        //printf("<<< send data: %s.\r\n", strData.data());
        g_wsClient->send(strData);
        //g_wsClient->sendBinary(strData);

        g_wsClient->poll(10); // 这个必须要调用，否则不能发送，发送跟接收都是异步的，都是在这个poll函数里监测处理的
        g_wsClient->dispatch(pfnOnHandleWSMessage);
#if 0
        while (g_wsClient->getReadyState() == WebSocket::OPEN/*g_wsClient->getReadyState() != WebSocket::CLOSED*/) {
            // TODO
            //g_wsClient->send(strData);
            //g_wsClient->sendBinary(strData);
            //g_wsClient->poll(10); // 这个必须要调用，否则不能发送，发送跟接收都是异步的，都是在这个poll函数里监测处理的
            //g_wsClient->dispatch(pfnOnHandleWSMessage);

            std::this_thread::sleep_for(std::chrono::milliseconds(5));
        }
#endif
        std::this_thread::sleep_for(std::chrono::milliseconds(100));

        g_wsClient->close();
        delete g_wsClient;
        g_wsClient = nullptr;
    }

#ifdef _WIN32
    WSACleanup();
#endif

    return 0;
}
